public class Main {
    public static void mergeSort(int[] array) {
        mergeSort(array, 0, array.length - 1);
    }

    private static void mergeSort(int[] array, int start, int end) {
        if (start >= end) {
            return;
        }

        int mid = start + (end - start) / 2;

        // 递归分治
        mergeSort(array, start, mid);
        mergeSort(array, mid + 1, end);

        // 原地合并
        merge(array, start, mid, end);
    }

    private static void merge(int[] array, int start, int mid, int end) {
        int i = start;       // 左区间起点
        int j = mid + 1;     // 右区间起点

        while (i <= mid && j <= end) {
            // 如果左边元素小于右边元素，不需要移动
            if (array[i] <= array[j]) {
                i++;
            } else {
                // 否则，插入右边的当前最小元素到左区间
                int temp = array[j];
                // 将左区间右移，给当前右元素腾位置
                System.arraycopy(array, i, array, i + 1, j - i);
                array[i] = temp;

                // 更新指针
                i++;
                j++;
                mid++;
            }
        }
    }

    public static void main(String[] args) {
        int[] array = {47, 14, 35, 8, 12, 16, 80, 22, 53};
        mergeSort(array);
        for (int num : array) {
            System.out.print(num + " ");
        }
    }
}
